{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "39c83836-f7dc-47a4-9183-c557560cd4ab",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install \"pymilvus[model]==2.5.10\" openai==1.82.0 requests==2.32.3 tqdm==4.67.1 torch==2.7.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "6f883050-6cbe-4815-b028-5d04bdaa7fc0",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "72"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from glob import glob\n",
    "import os\n",
    "\n",
    "os.chdir('D:/AI全栈')\n",
    "\n",
    "text_lines = []\n",
    "\n",
    "for file_path in glob(\"milvus_docs_2.4.x_en/en/faq/*.md\", recursive=True):\n",
    "    with open(file_path, \"r\") as file:\n",
    "        file_text = file.read()\n",
    "\n",
    "    text_lines += file_text.split(\"# \")\n",
    "   \n",
    "len(text_lines)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "07e2441d-1b29-41d7-a607-d914d5d032bb",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\ProgramData\\miniconda3\\envs\\deepseek\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    }
   ],
   "source": [
    "from pymilvus import model as milvus_model\n",
    "\n",
    "embedding_model = milvus_model.DefaultEmbeddingFunction()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "357889b8-c671-4059-816d-c947b4a1d7ec",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "success0.\n",
      "768\n",
      "[-0.04836059  0.07163021 -0.01130063 -0.03789341 -0.03320651 -0.01318453\n",
      " -0.03041721 -0.02269495 -0.02317858 -0.00426026]\n",
      "[-0.02752976  0.0608853   0.00388525 -0.00215193 -0.02774976 -0.0118618\n",
      " -0.04020916 -0.06023417 -0.03813156  0.0100272 ]\n",
      "success.\n",
      "success2.\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Creating embeddings: 100%|█████████████████████████████████████████████████████████| 72/72 [00:00<00:00, 241398.79it/s]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "success3.\n"
     ]
    }
   ],
   "source": [
    "from pymilvus import MilvusClient\n",
    "from pymilvus import model as milvus_model\n",
    "from tqdm import tqdm\n",
    "from glob import glob\n",
    "import os\n",
    "\n",
    "os.chdir('D:/AI全栈')\n",
    "\n",
    "text_lines = []\n",
    "\n",
    "for file_path in glob(\"milvus_docs_2.4.x_en/en/faq/*.md\", recursive=True):\n",
    "    with open(file_path, \"r\") as file:\n",
    "        file_text = file.read()\n",
    "\n",
    "    text_lines += file_text.split(\"# \")\n",
    "   \n",
    "len(text_lines)\n",
    "\n",
    "print(\"success0.\")\n",
    "\n",
    "embedding_model = milvus_model.DefaultEmbeddingFunction()\n",
    "\n",
    "test_embedding = embedding_model.encode_queries([\"This is a test\"])[0]\n",
    "embedding_dim = len(test_embedding)\n",
    "print(embedding_dim)\n",
    "print(test_embedding[:10])\n",
    "\n",
    "test_embedding_0 = embedding_model.encode_queries([\"That is a test\"])[0]\n",
    "print(test_embedding_0[:10])\n",
    "\n",
    "milvus_client = MilvusClient(uri=\"http://localhost:19530\")\n",
    "\n",
    "print(\"success.\")\n",
    "\n",
    "collection_name = \"my_rag_collection\"\n",
    "if milvus_client.has_collection(collection_name):\n",
    "    milvus_client.drop_collection(collection_name)\n",
    "\n",
    "milvus_client.create_collection(\n",
    "    collection_name=collection_name,\n",
    "    dimension=embedding_dim,\n",
    "    metric_type=\"IP\",  # 内积距离\n",
    "    consistency_level=\"Strong\",  # 支持的值为 (`\"Strong\"`, `\"Session\"`, `\"Bounded\"`, `\"Eventually\"`)。更多详情请参见 https://milvus.io/docs/consistency.md#Consistency-Level。\n",
    ")\n",
    "\n",
    "print(\"success2.\")\n",
    "\n",
    "\n",
    "data = []\n",
    "\n",
    "doc_embeddings = embedding_model.encode_documents(text_lines)\n",
    "\n",
    "for i, line in enumerate(tqdm(text_lines, desc=\"Creating embeddings\")):\n",
    "    data.append({\"id\": i, \"vector\": doc_embeddings[i], \"text\": line})\n",
    "\n",
    "milvus_client.insert(collection_name=collection_name, data=data)\n",
    "\n",
    "print(\"success3.\")\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "5914603c-4aa2-4f13-ab92-391ffaff5c5b",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\ProgramData\\miniconda3\\envs\\deepseek\\Lib\\site-packages\\tqdm\\auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
      "  from .autonotebook import tqdm as notebook_tqdm\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[\n",
      "    [\n",
      "        \" Where does Milvus store data?\\n\\nMilvus deals with two types of data, inserted data and metadata. \\n\\nInserted data, including vector data, scalar data, and collection-specific schema, are stored in persistent storage as incremental log. Milvus supports multiple object storage backends, including [MinIO](https://min.io/), [AWS S3](https://aws.amazon.com/s3/?nc1=h_ls), [Google Cloud Storage](https://cloud.google.com/storage?hl=en#object-storage-for-companies-of-all-sizes) (GCS), [Azure Blob Storage](https://azure.microsoft.com/en-us/products/storage/blobs), [Alibaba Cloud OSS](https://www.alibabacloud.com/product/object-storage-service), and [Tencent Cloud Object Storage](https://www.tencentcloud.com/products/cos) (COS).\\n\\nMetadata are generated within Milvus. Each Milvus module has its own metadata that are stored in etcd.\\n\\n###\",\n",
      "        0.65726637840271\n",
      "    ],\n",
      "    [\n",
      "        \"How does Milvus flush data?\\n\\nMilvus returns success when inserted data are loaded to the message queue. However, the data are not yet flushed to the disk. Then Milvus' data node writes the data in the message queue to persistent storage as incremental logs. If `flush()` is called, the data node is forced to write all data in the message queue to persistent storage immediately.\\n\\n###\",\n",
      "        0.6312144994735718\n",
      "    ],\n",
      "    [\n",
      "        \"How does Milvus handle vector data types and precision?\\n\\nMilvus supports Binary, Float32, Float16, and BFloat16 vector types.\\n\\n- Binary vectors: Store binary data as sequences of 0s and 1s, used in image processing and information retrieval.\\n- Float32 vectors: Default storage with a precision of about 7 decimal digits. Even Float64 values are stored with Float32 precision, leading to potential precision loss upon retrieval.\\n- Float16 and BFloat16 vectors: Offer reduced precision and memory usage. Float16 is suitable for applications with limited bandwidth and storage, while BFloat16 balances range and efficiency, commonly used in deep learning to reduce computational requirements without significantly impacting accuracy.\\n\\n###\",\n",
      "        0.6115781664848328\n",
      "    ]\n",
      "]\n"
     ]
    }
   ],
   "source": [
    "from pymilvus import MilvusClient\n",
    "import json\n",
    "from pymilvus import model as milvus_model\n",
    "\n",
    "embedding_model = milvus_model.DefaultEmbeddingFunction()\n",
    "\n",
    "\n",
    "milvus_client = MilvusClient(uri=\"http://localhost:19530\")\n",
    "\n",
    "collection_name = \"my_rag_collection\"\n",
    "\n",
    "question = \"How is data stored in milvus?\"\n",
    "\n",
    "search_res = milvus_client.search(\n",
    "    collection_name=collection_name,\n",
    "    data=embedding_model.encode_queries(\n",
    "        [question]\n",
    "    ),  # 将问题转换为嵌入向量\n",
    "    limit=3,  # 返回前3个结果\n",
    "    search_params={\"metric_type\": \"IP\", \"params\": {}},  # 内积距离\n",
    "    output_fields=[\"text\"],  # 返回 text 字段\n",
    ")\n",
    "\n",
    "retrieved_lines_with_distances = [\n",
    "    (res[\"entity\"][\"text\"], res[\"distance\"]) for res in search_res[0]\n",
    "]\n",
    "print(json.dumps(retrieved_lines_with_distances, indent=4))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "c1c7e8d5-e035-4fe9-9a4c-72fe85488ab9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-----------------------------------------\n",
      "<translated>Milvus 将数据存储在持久 storage 中的 incremental log中。 </translated>\n",
      "\n",
      "-----------------------------------------\n",
      "总耗时：10462116500\n",
      "-----------------------------------------\n"
     ]
    }
   ],
   "source": [
    "from pymilvus import MilvusClient\n",
    "import ollama\n",
    "from pymilvus import model as milvus_model\n",
    "\n",
    "embedding_model = milvus_model.DefaultEmbeddingFunction()\n",
    "\n",
    "milvus_client = MilvusClient(uri=\"http://localhost:19530\")\n",
    "\n",
    "collection_name = \"my_rag_collection\"\n",
    "\n",
    "question = \"How is data stored in milvus?\"\n",
    "\n",
    "search_res = milvus_client.search(\n",
    "    collection_name=collection_name,\n",
    "    data=embedding_model.encode_queries(\n",
    "        [question]\n",
    "    ),  # 将问题转换为嵌入向量\n",
    "    limit=3,  # 返回前3个结果\n",
    "    search_params={\"metric_type\": \"IP\", \"params\": {}},  # 内积距离\n",
    "    output_fields=[\"text\"],  # 返回 text 字段\n",
    ")\n",
    "\n",
    "retrieved_lines_with_distances = [\n",
    "    (res[\"entity\"][\"text\"], res[\"distance\"]) for res in search_res[0]\n",
    "]\n",
    "\n",
    "\n",
    "context = \"\\n\".join(\n",
    "    [line_with_distance[0] for line_with_distance in retrieved_lines_with_distances]\n",
    ")\n",
    "\n",
    "SYSTEM_PROMPT = \"\"\"\n",
    "Human: 你是一个 AI 助手。你能够从提供的上下文段落片段中找到问题的答案。\n",
    "\"\"\"\n",
    "\n",
    "USER_PROMPT = f\"\"\"\n",
    "请使用以下用 <context> 标签括起来的信息片段来回答用 <question> 标签括起来的问题。最后追加原始回答的中文翻译，并用 <translated>和</translated> 标签标注。\n",
    "<context>\n",
    "{context}\n",
    "</context>\n",
    "<question>\n",
    "{question}\n",
    "</question>\n",
    "<translated>\n",
    "</translated>\n",
    "\"\"\"\n",
    "\n",
    "stream = ollama.chat(\n",
    "    stream=True,\n",
    "    model='llama3.2:latest', # 修改大模型名称1\n",
    "    messages=[\n",
    "        {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n",
    "        {\"role\": \"user\", \"content\": USER_PROMPT}\n",
    "    ]\n",
    ")\n",
    "\n",
    "print('-----------------------------------------')\n",
    "for chunk in stream:\n",
    "    if not chunk['done']:\n",
    "        print(chunk['message']['content'], end=\"\", flush=True)\n",
    "    else:\n",
    "        print('\\n')\n",
    "        print('-----------------------------------------')\n",
    "        print(f'总耗时：{chunk['total_duration']}')\n",
    "        print('-----------------------------------------')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "50f70d43-7c4a-4605-8bd8-8a7af3444523",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
